home *** CD-ROM | disk | FTP | other *** search
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- Using & Interpreting ANSI Codes in Your ARexx Creations! v1.00
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- Alright, a few of you out there(you know who you are), have been throwing
- hints my way about the actual USAGE of ANSI codes in ARexx for CNet Amiga,
- so let's have some fun!
-
- Of all the available ANSI codes, the following can(and SHOULD) be used to
- the hilt in anything you write! ;-)
-
- ~[?;?;?m ~[?;?H ~[?A ~[?B ~[?C ~[?D ~[s ~[u
-
- These codes, coupled with some CNet ARexx Primitives(namely GETCHAR,
- MAYGETCHAR, TRANSMIT, and SENDSTRING) are all you really need to get your
- own programs using ANSI both effectively and efficiently. It should also be
- noted that the majority of the CNet Primitives used in this discussion are
- also part of the "ABBEREXX" standard, to which MANY Amiga BBS programs
- adhere to, so these explanations may prove useful for Non-CNet SysOps as
- well.
-
- Before continuing, please take a moment to install the following little
- scripts, which I have found to be extremely helpful in the creation of my
- ARexx projects, and you might as well:
-
- NOTE: If you'd like to SKIP the following sections and get right to the
- ANSI-meat portion of this document, search for STARTING WITH ANSI!
- ~~~~~~~~~~~~~~~~~~
- RunARexx
- ~~~~~~~~
- Copied somewhere on your system, like in DOORS:, you can then create the
- following line in your BBSMENU file, to the bottom of Menu # 3:
-
- RUNA, RUNArexx `31 | {#0doors:RunARexx}
- ^ ^
- Who Can Use RUNA? Control-Q character.
-
- This command allows you to "test drive" any ARexx program of your choosing
- from within CNet proper, just like CNet's internal RUN command can do for any
- CNetC programs. You can either type:
-
- CNet: runa<enter>
-
- - Then type in a <path>filename, or...
-
- CNet: runa <path>filename
-
- Provided the file exists at stated path, it will be executed, however you
- will be notified if the file is missing.
-
- NewDoor & TestDoor
- ~~~~~~~ ~~~~~~~~
- "NewDoor" is an Arexx template to get you started, while "TestDoor" is
- a file you can run from anywhere on your system by adding the following to
- the end of Menu # 3 in your BBSMENU command:
-
- TEST `31 | {#0doors:TestDoor}
-
- Whenever you feel like "experimenting" with a new fragment of Arexx code,
- copy it into the "TestDoor" script, then type TEST from anywhere on your BBS,
- even while inside one of CNet's editors(using the .* or CTRL-C commands)!
-
- These files can act as the "basic framework" for any ARexx creations you
- create. They are both virtually identical. The TOP portion of each file holds
- the following lines:
-
- /**************************************************************************\
- $VER: Program Name, v0.00 (DD-MMM-YY) by Handle of BBS Name!
- \**************************************************************************/
- options results;signal on SYNTAX;signal on ERROR;signal on IOERR
- /*ver=word(sourceline(2),?);a=word(sourceline(2),?);parse var a "("vdate")"*/
- tr=transmit;se=sendstring;gc=getchar;gu=getuser;gs=getscratch;mg=maygetchar
- a='rexxsupport.library';if ~show('l',a) then if ~addlib(a,0,-30) then exit
-
- You should modify the 2nd and 5th lines above to reflect the name and
- version of the file you are creating. If you REMOVE the /* and */ from line
- 5, then replace the two "?"'s on the line with the word position of the
- version number and date of creation, you'll then have two variables you can
- use anywhere in your program when you want to print the VERSION or DATE of
- LAST modification. In the above example, you'd replace the first ? with a 4,
- because the version number(v0.00) is the FOURTH word on the line. Likewise,
- you'd replace the second ? with a 5, as the date(DD-MMM-YY) is the FIFTH word
- to appear on line 5. Depending on how you set up line 2, these numbers will
- change, so be sure to update them correctly, before attempting to use the
- "ver" and "vdate" variables yourself. A line like the following shows you how
- these variables could be used in a TRANSMIT variable:
-
- transmit "My Program, "ver", last modified on: "vdate"!"
-
- The 6th and 7th lines listed above offer you a bit more flexability in
- your coding. The 6th line creates a series of command "aliases", which you
- can then opt to use INSTEAD of typing the entire command. For instance, if a
- program you create uses the TRANSMIT command 50 times, the entire word of
- TRANSMIT would appear, versus just the two characters TR. So what? Well, when
- using TRANSMIT, it's costing you 8 bytes, while if you use TR, it only costs
- you 2 bytes. Again, so?!? Use the above example. If TRANSMIT is used 50 times
- in your program, and if using TR saves you 6 bytes each time, 50x6=300 bytes.
-
- Now, you continue to do this with the other aliases: SE, GC, GU, GS, and
- MG, then do the math, oftentimes this can lead to anywhere from 3K to 10K
- savings. You should REMOVE any aliases you are NOT using, and create any NEW
- aliases that YOU find helpful. (Keep in mind, however, that if you'll only be
- using a given command once or twice, then it won't help to create an alias,
- as in these instances, it could result in your program actually taking up
- MORE bytes than it really could).
-
- The 7th line simply makes the ARexx Support Library available to you. If
- this line is MISSING, and you attempt to use a support command, you'll run
- into problems later on. The following commands are stored in this library, so
- if your program is NOT using any of these commands, you could DELETE the 7th
- line from the NewDoor program:
-
- ALLOCMEM, BADDR, CLOSEPORT, DELAY, DELETE, FORBID, FREEMEM, GETARG,
- GETPKT, MAKEDIR, NEXT, NULL, OFFSET, OPENPORT, PERMIT, RENAME, REPLY,
- SHOWDIR, SHOWLIST, STATEF, TYPEPKT, and WAITPKT.
-
- I'd like to further note that the "dos" type commands listed above, like
- DELETE, MAKEDIR, and RENAME are actual ARexx Primitives included as new Arexx
- commands, and are NOT the same as if you call one of the DOS commands using
- the same name. For example:
-
- address command "c:delete ram:test"
- and
- call DELETE("ram:test")
-
- Both do the same thing, however the ADDRESS command is internal to the
- main "rexxsyslib.library", so does NOT make use of the support library, while
- using the DELETE() function DOES use the "rexxsupport.library".
-
- Alright, the BOTTOM of both scripts looks like this:
-
- exit
- CHECK:;if ARG() & ARG(1)~='###PANIC' then return ARG(1)
- getcarrier;if result='TRUE' then if ARG() then return ARG(1);else return
- /* Place any "cleanup" or "reenable" code here, before exiting! */
- logentry 'Lost Carrier!!';bufferflush;exit
- SYNTAX:;ERROR:;IOERR:;e1='n1 Error: 'rc' ('errortext(rc)')'
- e2=' Line: 'left(sigl,4)'File:';gu 1311992;a=result;gu 1311960
- b=result;c='"'a||b', 'ver'"';e2=e2' 'c;tr e1;tr e2;logentry e1
- logentry e2;e=translate(sourceline(sigl),"\{","");do while e~=''
- e3='Source: 'left(e,37);tr e3;logentry e3;e=substr(e,38);end;bufferflush
- /**************************************************************************\
- \****************************************** BBS Name (AAA)/PPP-SSSS *******/
-
- The CHECK: routine is the latest "loss of carrier" check routine that
- I've been using. To use the routine, simple CALL it whenever you want to
- check for carrier, preferably whenever you're awaiting input from the user,
- as in this example:
-
- sendstring "Do what now? " ; getchar ; a=result ; call CHECK
-
- You don't have to go OVERBOARD with your usage of this command, but you
- DO want to make sure you include it anywhere that might put the user in a
- dead-lock loop(for instance, if you're sking the user to hit 1, 2, or 3, and
- if your program will continually ask for one of these keys UNTIL one of them
- has been pressed, if the user loses carrier at this prompt, the script will
- put itself into a "dead-lock" and you'll have a serious problem.
-
- While creating scripts, if you discover a script that IS in a dead-lock,
- there's a program called HI, located in the "Sys:Rexxc/" directory that you
- can use to HALT or STOP the Arexx program, however further note that using
- this command halts ALL currently running ARexx programs, so if users on other
- ports are also using ARexx programs, they'll be kicked out of THEIR programs
- as well.
-
- Lastly, note the comment line in the CHECK: routine:
-
- /* Place any "cleanup" or "reenable" code here, before exiting! */
-
- If there is any DATA that would need to be saved in order to save the
- integrity of what the user was doing, then place calls to your SAVE routines
- within this routine as well. Also, if your program MODIFIES one of the user's
- settings(for instance, if it turns the MORE mode OFF or MUFFLES the user from
- all other users), then be sure to REVERSE the process in this routine as well,
- so that if a user was NOT muffled when going INTO your program, and they lose
- carrier, the next time they log on, they should STILL NOT be muffled.
-
- The SYNTAX:;ERROR:;IOERR: routine is the latest error-check routine I've
- been using myself, and is actually quite powerful in itself. Not only will
- the user(or you) be alerted as soon as a "capturable" error has occurred, but
- the exact same message will be appended to either your "calls" log, or an
- "ARexxSays" log, if you have one defined. The format of the output is such
- that it will look as readable as possible when presented in the log. All MCI
- commands located on the line are changed to their \{ non-destructive states,
- so you can be sure to see the line as it would appear if you were editing it
- in a text editor.
-
- The comment lines at the bottom of the listing are included only as a
- means of insuring the entire file is intact. You can put your BBS's name in
- this comment field if you so wish.
-
- When using the "NewDoor" file, train yourself to do the following:
-
- 1. Load the "NewDoor" file into your text editor.
- 2. Change the 2nd and 5th lines as needed.
- 3. Now SAVE AS the file as the NAME you'd like to give your creation.
- 4. NOW start creating your coding.
-
- This way, you won't discover later on that you no longer HAVE the NewDoor
- template to use, because it was morphed into your latest ARexx creation. If
- using a Dock-type program, like Tool Manager, you can even opt to create an
- instant way to launch both of these programs. For me, because I create LOTS
- of different programs, I have them as buttons on a "Programming Dock" on my
- WorkBench screen, so creating a NEW program, or testing some new theory is
- only a mouse-click away!
-
- -----------------------------------------------------------------------------
- STARTING WITH ANSI!
- ~~~~~~~~~~~~~~~~~~
- Let's start with a look at the Amiga Keyboard. It is possible to capture
- keypresses from NUMEROUS additional keys, besides the number and letter keys.
- This includes the cursor-arrow keys, the escape key, the backspace key, the
- delete key, the enter/return key, the tab key, as well as any/all qualified
- keystrokes(those gotten while first holding SHIFT, CTRL, ALT, or a combination
- of these).
-
- Among those keystrokes NOT able to be "caught" by ARexx include the ten
- function keys(and their qualified states), the help key, the caps lock key,
- and any qualified keystrokes using the left or right Amiga Command keys.
-
- The Numeric Keypad to the right of the main keyboard maps to the same
- keystrokes as those keys shown on the face of each key. (Meaning the 7 acts
- the same as a 7 on the main keyboard, however the `home' function cannot be
- mapped to it's own value through Arexx, nor can any of the other `fronts').
-
- For our first look at ARexx and ANSI, let's explore the keyboard. Type or
- copy the following into the included "TestDoor" script, then use the TEST
- command to execute the script:
-
- START:
- se "Press any key now(press Q to quit): "
- gc ; k=result ; tr k
- if k="Q" then exit
- signal START
-
- The above script will loop forever, until such a time as you press the "Q"
- key on your keyboard. After using it for a bit, you'll notice that there are
- many keys you can press which return visual(printable) results, which can all
- be used within your ARexx creations.
-
- While still running the above program, try pressing the following keys:
-
- enter, tab, backspace, ctrl-q, ctrl-s, ctrl-y
-
- There are others as well, but you get my drift, right? :-) These keystrokes
- DID return a value(as shown by the prompt advancing a line), however in their
- current state, the returned results are unusable. Now try pressing the cursor
- arrow keys, specifically noting what happens to the prompt(especially the next
- one printed after pressing an arrow key). Did you notice the "P" in the text
- for the prompt was suppressed? Remember this behavior for a bit. Lastly, try
- typing an "A" on the keyboard. Did it print an UPPER or lowercase letter? See
- if you can get it to print the opposite case letter.
-
- As shown above, the initial script "sorta" works, and in fact, works GREAT
- for some applications, but not for others, so let's change the script a bit.
- Try copying the following into your "TestDoor" script ABOVE the script we
- were working with earlier:
-
- START2:
- se "Press any key now(press Q to quit): "
- do until k~="NOCHAR" ; mg ; k=result ; end
- tr c2d(k) ; if k="q" then exit
- signal START2
-
- After running this one for awhile, you'll notice somthing VERY strange.
- Instead of seeing the printable characters you WANTED, you're seeing NUMBERS,
- nothing but NUMBERS. Now, before you get in a tizzy, try those "bad" keys
- again. Remember:
-
- enter, tab, backspace, ctrl-q, ctrl-s, ctrl-y
-
- Also, see what happens when you press "A", "SHIFT-A", "CTRL-A", etc. I'm
- hoping you're noticing that even though it's NUMBERS being returned, they are
- all UNIQUE from each other.
-
- Now, try typing the cursor arrows again. Notice the output this time is
- NUMBERS again, but did you ALSO notice that it printed THREE numbers, instead
- of ONE, as all the other keystokes did? Are you seeing what's happening yet?
-
- No? Would it help if I told you that all these NUMBERS it's printing right
- now are the ASCII equivalents of the actual characters? If you were to look
- through an ASCII chart, here's what you'd find for the three numbers that are
- printed when you press the UP cursor arrow:
-
- Press any key now(press Q to quit): 27 <--- An ESCape code.
- Press any key now(press Q to quit): 91 <--- An open bracket ([).
- Press any key now(press Q to quit): 65 <--- A capital letter A.
-
- In other words: ESC [ A
-
- Does THAT look a bit more familiar?!? hehe I should hope so. You'll notice
- similar strings of numbers for the other arrows:
-
- 27-91-66 <--- DOWN cursor arrow.
- 27-91-67 <--- RIGHT cursor arrow.
- 27-91-68 <--- LEFT cursor arrow.
-
- Before we continue, try pressing the ESCape key while running the script:
-
- Press any key now(press Q to quit): 27
-
- Note that it returns the same 27 that was also used in the cursor keystroke
- lists. So, what does all this MEAN? Well, it means that it's possible for us
- to capture these keystrokes, however depending on WHICH keystrokes we want,
- we have to go about GETTING them through different means.
-
- Let's take a look at a script with a bit more meat. Copy the following to
- your "TestDoor" script ABOVE the START2: routine we just finished with:
-
- KEYS1:
- tr "Press some keys now..."
- do forever until k="q"
- mg ; k=result ; kk="" ; if k="NOCHAR" then iterate
- if c2d(k)=27 then do 2 ; mg ; kk=result ; end
- select
- when c2d(k)=27 & kk="NOCHAR" then tr "You pressed the ESCape key..."
- when kk="A" then tr "You pressed the UP cursor arrow..."
- when kk="B" then tr "You pressed the DOWN cursor arrow..."
- when kk="C" then tr "You pressed the RIGHT cursor arrow..."
- when kk="D" then tr "You pressed the LEFT cursor arrow..."
- when c2d(k)=13 then tr "You pressed the ENTER key..."
- when c2d(k)=9 then tr "You pressed the TAB key..."
- when c2d(k)=127 then tr "You pressed the DELETE key..."
- when c2d(k)=8 then tr "You pressed the BACKSPACE key..."
- when c2d(k)=32 then tr "You pressed the SPACEBAR key..."
- otherwise tr "You pressed the "k" key..."
- end
- end
- exit
-
- The above routine will successfully capture ANY of the "available" keys.
- You'll notice that the MAYGETCHAR command has been used solely in the routine,
- however it could be slightly rewritten to use the GETCHAR command instead:
-
- KEYS2:
- tr "Press some keys now..."
- do forever until k="Q"
- gc ; k=result ; kk="" ; if c2d(k)=27 then do 2 ; gc ; kk=result ; end
- select
- when c2d(k)=27 & kk="" then tr "You pressed the ESCape key..."
- when kk="A" then tr "You pressed the UP cursor arrow..."
- when kk="B" then tr "You pressed the DOWN cursor arrow..."
- when kk="C" then tr "You pressed the RIGHT cursor arrow..."
- when kk="D" then tr "You pressed the LEFT cursor arrow..."
- when c2d(k)=13 then tr "You pressed the ENTER key..."
- when c2d(k)=9 then tr "You pressed the TAB key..."
- when c2d(k)=127 then tr "You pressed the DELETE key..."
- when c2d(k)=8 then tr "You pressed the BACKSPACE key..."
- when c2d(k)=32 then tr "You pressed the SPACEBAR key..."
- otherwise tr "You pressed the "k" key..."
- end
- end
- exit
-
- You'll notice the KEYS2 routine is a bit shorter than the KEYS1 routine,
- however KEYS2 lacks the ability to map UPPER versus lowercase letter keys.
- The MAYGETCHAR command returns the ACTUAL key pressed, which means "a" is
- returned if you press the "a" key, while "A" is returned if "SHIFT-A" was
- pressed.
-
- Another nice advantage to using MAYGETCHAR is that it means precisely what
- it's name implies, the Amiga MAY get a character, or it MAY NOT. If a key was
- NOT caught, MAYGETCHAR returns the text string "NOCHAR". Well, you're most
- probably thinking, "So what?", right? Well, not HAVING to wait for a keypress
- can come in REAL handy when writing programs. For instance, let's take a GAME
- for an example. I'm thinking of the game Tetris. If you opt NOT to move one
- of the shapes to the left or the right, and you opt NOT to rotate the shape,
- what happens to the shape? Does it just sit there WAITING for you to tell it
- what you want it to do? Yeah, I wish! No, it continues to move DOWN the game
- screen. It's this same MAYGETCHAR type of operation that allows a game like
- Tetris to do that:
-
- SHAPE:
- - Display the shape.
- MOVE:
- - Did user hit LEFT or RIGHT?
- - Yes - then move the shape...
- - No - then continue...
- - Did user ROTATE the shape?
- - Yes - then rotate the shape...
- - No - then continue...
- - Move the shape DOWN one line!
- - Did shape hit bottom yet?
- - Yes - then go to SHAPE:
- - No - then go back to MOVE:
-
- What's more, you could also have things like a SCORE being updated while
- waiting for the keystrokes. You could display the NEXT shape or two, etc.
- without having to WAIT for a keystroke.
-
- Now, you have to be a BIT careful here, as you don't want to spend TOO
- MUCH time doing other things, else you'll lose the seamless flow to the
- end result you're looking to accomplish.
-
- Alright, so we know HOW to get the characters from the keyboard, but how
- do we then create an ARexx routine to USE these characters? Let's take yet
- another ARexx routine. Copy this one ABOVE the KEYS1 (or KEYS2) routine you
- were last working with, then run the "TestDoor" script again:
-
- tr "f1.--.--.--.--.--.--.--.--.--.--."
- do 9;tr "| | | | | | | | | | |"
- tr "|--+--+--+--+--+--+--+--+--+--|";end
- tr "| | | | | | | | | | |"
- tr "`--^--^--^--^--^--^--^--^--^--'"
- row=1 ; col=1
- MOVE:
- se ""row*2";"col*3-1"H"
- gc ; k=result ; kk="" ; if c2d(k)=27 then do 2 ; mg ; kk=result ; end
- if c2d(k)=27 & kk="NOCHAR" then do ; se "1HExiting..." ; exit ; end
- if c2d(k)=13 then do ; se "1HRow: "row", Column: "col ; exit ; end
- if kk="A" & row>1 then row=row-1
- if kk="B" & row<10 then row=row+1
- if kk="C" & col<10 then col=col+1
- if kk="D" & col>1 then col=col-1
- signal MOVE
-
- This routine starts by printing a simple 10x10 grid, with an Ascii Frame
- around it. The MOVE: routine uses the same techniques discussed above, with
- the addition of two variables, "row" and "col". These variables have their
- values changed, dependent upon which cursor-arrow keys you press. This is
- evident in the program by the cursor moving around within the grid. If we
- press ESC, we can EXIT the program, but if we press ENTER, we exit as well
- as being told WHICH row and column we were IN before we left.
-
- This is a fairly simple grid technique with some limitations. For one, it
- uses finite borders. This means that once we reach one of the borders, that's
- as far as the current script will allow us to go. With some slight changes to
- the four "if kk=..." lines, we can make this movement more powerful:
-
- if kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
- if kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
- if kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
- if kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
-
- With the above changes, the script will allow the cursor to wrap around
- the borders, which allows for a bit more freedom of movement.
-
- Another problem with the script occurs if we give some thought as to WHO
- might be using the program. Some IBM and Amiga users do not have separate
- arrow keys on their keyboards. These users rely on using the Numeric Keypad's
- arrow keys, which reside on the 2, 4, 6, and 8 keys. We could further modify
- the above lines to take these people into consideration as well:
-
- if k="8" | kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
- if k="2" | kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
- if k="6" | kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
- if k="4" | kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
-
- Not too much extra to satisfy these users, huh? Well, what else could the
- "little script that could" use? How about getting rid of the cursor? If we
- change the first few lines of the MOVE: routine to use the MAYGETCHAR command,
- instead of the GETCHAR command, we can solve this problem:
-
- MOVE:
- se ""row*2";"col*3-1"H"
- do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
- if c2d(k)=27 then do 2 ; mg ; kk=result ; end
-
- However, if you try these changes, you'll notice another problem, as there
- is no way of knowing WHERE you are, so we need a VISIBLE character to act as
- our prompt character. This can be accomplished by adding 1 character to the
- first line of the MOVE: routine:
-
- se ""row*2";"col*3-1"H>"
-
- Note the addition of the > character as the second last character on the
- line above. This gives us a better looking cursor over the "big block", but
- because this is a PRINTABLE character, you'll notice a trail of >'s follow
- you as you traverse the grid. To fix this problem, we need to add one line
- right above those "if kk=..." lines, like this:
-
- tr ""row*2";"col*3-1"H "
-
- Note that in the above line, a SPACE appears where the > appeared in the
- line that printed the prompt. What we're doing is using the ANSI positioning
- codes to print the cursor, print a space OVER the cursor, modify the position
- of the cursor, then reprint the cursor. Here's what the entire routine should
- now look like:
-
- tr "f1.--.--.--.--.--.--.--.--.--.--."
- do 9;tr "| | | | | | | | | | |"
- tr "|--+--+--+--+--+--+--+--+--+--|";end
- tr "| | | | | | | | | | |"
- tr "`--^--^--^--^--^--^--^--^--^--'"
- row=1 ; col=1
- MOVE:
- se ""row*2";"col*3-1"H>"
- do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
- if c2d(k)=27 then do 2 ; mg ; kk=result ; end
- if c2d(k)=27 & kk="NOCHAR" then do ; se "1HExiting..." ; exit ; end
- if c2d(k)=13 then do ; se "1HRow: "row", Column: "col ; exit ; end
- tr ""row*2";"col*3-1"H "
- if k="8" | kk="A" then do ; row=row-1 ; if row<1 then row=10 ; end
- if k="2" | kk="B" then do ; row=row+1 ; if row>10 then row=1 ; end
- if k="6" | kk="C" then do ; col=col+1 ; if col>10 then col=1 ; end
- if k="4" | kk="D" then do ; col=col-1 ; if col<1 then col=10 ; end
- signal MOVE
-
- Well, there you have it! It's actually not that hard to do. Now, there are
- some "extras" you might want to toss into a routine like the above. Perhaps
- you'd like to be able to "drop" something where the cursor was located, maybe
- when the user presses their ENTER keys or something. Again, nothing more than
- a slight modification to an existing line above, in this case the line that
- starts with "if c2d(k)=13 then..."
-
- if c2d(k)=13 then do ; se ""row*2";"col*3"H#" ; signal MOVE ; end
-
- The above change will allow you to place a # character to the RIGHT of the
- > prompt, whenever you press your ENTER key. Note, however, that once the # is
- placed, it's there for GOOD. To REMOVE it, you'd have to either define a 2nd
- keystroke to remove/lift the piece, or else create an arrayed variable that
- would house the contents of each "spot" within the grid.
-
- I'll shy away from pursuing that any farther, as that's getting a bit more
- into Game Theory, instead of ANSI coding, but you get the general idea!
-
- Alright, so what ELSE is there to ANSI coding in ARexx? Well, how about the
- creation of an AnsiARexx editor, which is used in exactly the same way as one
- of CNet's VDE editors? This is yet another feat for the serious ANSI-ARexx
- coder. Let's take a look at a fairly simple AnsiARexx editor, which can be
- used to modify your mailing address:
-
- gu 3 ; realname=result ; gu 6 ; street=result
- gu 4 ; citystate=result ; gu 5 ; zip=result
- kb.1=" Real Name:" ; kb.2="Street Address:"
- kb.3=" City, State:" ; kb.4=" Zip Code:"
- tr "f1z4c7 Simple AnsiARexx VDE Editor z0n1"
- tr "z4c7 Real Name:z0 c3"realname
- tr "z4c7Street Address:z0 c3"street
- tr "z4c7 City, State:z0 c3"citystate
- tr "z4c7 Zip Code:z0 c3"zip
- kb=1 ; kbt=4
- EDIT:
- se ""kb+2";1Hz7c4"kb.kb"z0q1"
- do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
- if c2d(k)=27 then do 2 ; mg ; kk=result ; end
- if c2d(k)=27 & kk="NOCHAR" then do ; tr "1HExiting..." ; exit ; end
- se ""kb+2";Hz4c7"kb.kb"z0"
- if kk="A" then do ; kb=kb-1 ; if kb<1 then kb=kbt ; end
- if kk="B" then do ; kb=kb+1 ; if kb>kbt then kb=1 ; end
- signal EDIT
-
- The above code initially reads in your current values, creates a set of
- Ansi buttons(the kb. array), as well as setting up two pointers, kb, which
- is used to specify which button will be initially highlighted, and kbt which
- tells the script the total number of buttons defined. The EDIT: routine uses
- the same techniques we've already seen, except instead of printing the one
- character > prompt, we're printing the kb. button. Only two cursor keys have
- been defined, as there's only one column of data. The UP and DOWN arrows can
- be used to move the highlighted button up or down and the ESCape key will
- exit the editor.
-
- To actually EDIT the data, we need to define what the ENTER key should do,
- based on the value of the kb variable, as that will point at WHICH button was
- highlighted when you pressed ENTER. The following code is placed BELOW the
- `if kk="B"...' line above:
-
- if c2d(k)=13 then do
- if kb=1 then do ; se ""kb+2";17Hr1c3L1305640 #"realname"}I20 34}"
- gu 70;realname=result;signal EDIT;end
- if kb=2 then do ; se ""kb+2";17Hr1c3L1305640 #"street"}I20 30}"
- gu 70;street=result;signal EDIT;end
- if kb=3 then do ; se ""kb+2";17Hr1c3L1305640 #"citystate"}I20 22}"
- gu 70;citystate=result;signal EDIT;end
- if kb=4 then do ; se ""kb+2";17Hr1c3L1305640 #"zip"}I20 10}"
- gu 70;zip=result;signal EDIT;end
- end
-
- As you can see, the above bit of code is almost as big as the EDIT: routine
- itself. I didn't say it would be short! hehe I'm using the {L } MCI command to
- load the data into the "line input buffer". The {I20 } MCI command is used to
- get a line of input from the user. The "20" is the MCI Environment setting,
- and actually stands for 4+16. The 4 means to start with the line input buffer,
- and the 16 means to make the first character of every word entered UPPER case.
-
- As shown, the above is a 90% duplicate of the CNetC VDE editors. CNet's
- internal VDE editors do two more things: they show the max length of input
- possible, while editing a field, and they utilize a "smart" save feature. The
- following is the complete version of this editor:
-
- gu 3 ; realname=result ; gu 6 ; street=result
- gu 4 ; citystate=result ; gu 5 ; zip=result
- kb.1=" Real Name:" ; kb.2="Street Address:"
- kb.3=" City, State:" ; kb.4=" Zip Code:"
- tr "f1z4c7 Simple AnsiARexx VDE Editor z0n1"
- tr "z4c7 Real Name:z0 c3"realname
- tr "z4c7Street Address:z0 c3"street
- tr "z4c7 City, State:z0 c3"citystate
- tr "z4c7 Zip Code:z0 c3"zip
- kb=1 ; kbt=4 ; save=0
- EDIT:
- se ""kb+2";1Hz7c4"kb.kb"z0q1"
- do until k~="NOCHAR" ; mg ; k=result ; end ; kk=""
- if c2d(k)=27 then do 2 ; mg ; kk=result ; end
- if c2d(k)=27 & kk="NOCHAR" then signal SAVE
- se ""kb+2";Hz4c7"kb.kb"z0"
- if kk="A" then do ; kb=kb-1 ; if kb<1 then kb=kbt ; end
- if kk="B" then do ; kb=kb+1 ; if kb>kbt then kb=1 ; end
- if c2d(k)=13 then do
- if kb=1 then do ; se ""kb+2";17Hz3L1305640 #"realname"}s"
- se left("",34)"uz3c4I20 34}";gu 70;a=result;save=(a~=realname)
- se "z0c3u"left(a,34);realname=a;signal EDIT;end
- if kb=2 then do ; se ""kb+2";17Hz3L1305640 #"street"}s"
- se left("",30)"uz3c4I20 30}";gu 70;a=result;save=(a~=street)
- se "z0c3u"left(a,30);street=a;signal EDIT;end
- if kb=3 then do ; se ""kb+2";17Hz3L1305640 #"citystate"}s"
- se left("",22)"uz3c4I20 22}";gu 70;a=result;save=(a~=citystate)
- se "z0c3u"left(a,22);citystate=a;signal EDIT;end
- if kb=4 then do ; se ""kb+2";17Hz3L1305640 #"zip"}s"
- se left("",10)"uz3c4I20 10}";gu 70;a=result;save=(a~=zip)
- se "z0c3u"left(a,10);zip=a;signal EDIT;end
- end
- signal EDIT
- SAVE:
- if save=0 then tr "1HNo changes made... Exiting..."
- else tr "1HChanges Made! Data automatically SAVED, then exit..."
- exit
-
- I won't give you the actual SAVE coding, as I want this to be an example
- only. You should be able to create the SAVE code yourself, if you actually
- WANTED to use this editor. :-)
-
- Well, that's enough of the "heavy duty" Ansi Coding. For our last example,
- lets have some fun on the screen itself by creating a "kaleidoscope" type of
- program using ANSI. Copy the following ABOVE the last routine you pasted into
- the TestDoor script:
-
- a=random(,,time("s")) ; se "f1Hello"
- gu 27 ; cols=result ; gu 1100468 ; rows=result
- do forever until k="q" ; mg ; k=result
- row=random(1,rows) ; col=random(1,cols-1)
- co=substr("0123456789abcdef",random(1,16),1)
- char=d2c(random(32,190))
- se ""row";"col"Hc"co||char
- end ; tr "1HGood Bye!"
- exit
-
- The above will go on forever, until you press the "Q" key on the keyboard.
- Being completely random, it produces a mish-mash design on the screen. Here's
- another that looks a bit more like the kaleidoscopes you may remember:
-
- a=random(,,time("s")) ; se "f1Hello"
- gu 27 ; cols=result ; gu 1100468 ; rows=result
- do forever until k="q" ; mg ; k=result
- row=random(1,rows%2) ; col=random(2,cols%2)-1
- co=substr("0123456789abcdef",random(1,16),1)
- char=d2c(random(161,255))
- se ""row";"col"Hc"co||char
- se ""row";"cols-col"Hc"co||char
- se ""rows-row";"col"Hc"co||char
- se ""rows-row";"cols-col"Hc"co||char
- end ; tr "1HGood Bye!"
- exit
-
- The above version chops the visible screen into 4 quadrants, then mirrors
- the chosen character into each quadrant as a certain distance from the center
- of the screen to create the design.
-
- Lastly, try this version:
-
- a=random(,,time("s")) ; se "f1Hello"
- gu 27 ; cols=result ; gu 1100468 ; rows=result
- do forever until k="q" ; mg ; k=result
- row=random(1,(rows%2)-5) ; col=random(1,(cols%2)-5)-1
- co=substr("0123456789abcdef",random(1,16),1)
- char=d2c(random(161,255)) ; a=random(1,5)
- do i=1 to a
- se ""row+i";"col+i"Hc"co||char
- se ""row+i";"cols-col-i"Hc"co||char
- se ""rows-row-i";"col+i"Hc"co||char
- se ""rows-row-i";"cols-col-i"Hc"co||char
- end i
- end ; tr "1HGood Bye!"
- exit
-
- By introducing a second loop to the action, actual strings of characters
- are printed to the screen, instead of individual characters. This idea could
- be taken even further, perhaps by changing the direction of the string, or
- producing strings that weren't necessarily straight lines, but perhaps ones
- that curved, etc. open up a plethora of different possibilities.
-
- Well, I've tried to think of as many different ways as possible where you
- might use ANSI coding with your ARexx commands to further enhance the programs
- you create. It is my sincere hope that some or all of the above material will
- prove useful for you in the things that you create.
-
- If you'd like to take any of the previous examples to the next, logical
- step, but still aren't quite sure how to proceed, feel free to contact me with
- any questions you may have. I will definately have wanted you to have read
- through this document, and have at least gotten some sort of framework laid
- out, but will gladly give you the next building block towards your finished
- creation! :-)
-
- Here's how I may be contacted:
-
- Through Internet EMail: dotoran@bluemoon.net
-
- Through World Wide Web: http://www.bluemoon.net/~dotoran
-
- Through FidoNet Network: dotoran@1:260/121.0
-
- Through CLink Network: dotoran@911:6840/2.0
-
- Through Snail Mail: David M. Weeks
- 318 Woodside Avenue
- Buffalo, NY 14220-2015
- ATTN: Dotoran
-
- If you feel what you need to ask could be of public interest, you can post
- a message, addressed to Dotoran, to one of the following messaging echoes:
-
- The CNET and CNET_BBS message echoes of FidoNet.
-
- The CLINKCNETAMIGA and CLINKCNETPROG message echoes of CLink.
-
- The "CNet Mailing List" on the Internet.
-
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
- Created using CED by Dotoran of Frontiers BBS (716)/823-9892!
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-